#pragma once

#include "Socket.hpp"
#include <iostream>
#include <pthread.h>
#include <functional>

// http协议底层为tcp协议
using func_t = std::function<std::string(std::string &request)>;

class TcpServer;

class ThreadData
{
public:
    ThreadData(TcpServer *tcp_this, network::Socket *sockp) : _this(tcp_this), _sockp(sockp)
    {}

public:
    TcpServer *_this;
    network::Socket *_sockp;
};

class TcpServer
{
public:
    TcpServer(int port, func_t request_handler) : _port(port), _listen_socket(nullptr), _request_handler(request_handler)
    {
        _listen_socket->BuildListenSocketMethod(_port, network::backlog);
    }

    ~TcpServer()
    {
        delete _listen_socket;
    }

    static void* ThreadRun(void* args)
    {
        pthread_detach(pthread_self()); // 分离线程: 线程结束时自动回收资源
        ThreadData* td = static_cast<ThreadData*>(args);
        std::string http_request; // http请求

        // 接收请求
        if(td->_sockp->Recv(&http_request, 4096)) {
            // 
            std::string http_response = td->_this->_request_handler(http_request);
            if(!http_request.empty()) {
                td->_sockp->Send(http_response); // 发送响应
            }
        }

        td->_sockp->CloseSocket();
        delete td->_sockp;
        delete td;
        return nullptr;
    }

    // 循环监听
    void Loop()
    {
        while(true) 
        {
            std::string peerip;
            uint16_t peerport;
            network::Socket* newSock = _listen_socket->AcceptConnection(&peerip, &peerport);
            if(!newSock) {
                // std::cerr << "accept error" << std::endl;
                continue;
            }

            std::cout << "new connection from " << peerip << ":" << peerport << std::endl;
            ThreadData* td = new ThreadData(this, newSock);
            pthread_t tid;
            pthread_create(&tid, nullptr, ThreadRun, td);
        }
    }

private:
    int _port;
    network::Socket *_listen_socket;
public:
    func_t _request_handler;
};